package com.example.verify;

import com.example.annotations.Valid;
import com.example.verify.handler.ParamsVerifyHandler;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * 对象属性校验注解处理器
 * @Author: chen
 * @CreateTime: 2022-08-16
 * @Version: 1.0
 */

@Aspect
@Component
public class MyAnnotationsHandler {

    @Pointcut("execution(* com.example.controller.*.*(..))")
    public void pointCut() {
    }

    // 增强方法
    @Around("pointCut()")
    public Object verifyParams(ProceedingJoinPoint joinPoint) throws Throwable{
        Object[] args = joinPoint.getArgs();
        Object result = joinPoint.proceed(args);
        // 方法签名
        Signature signature = joinPoint.getSignature();
        // 获取的是代理类的method对象
        Method method = ( (MethodSignature)signature ).getMethod();
        // 这个方法才是目标对象上有注解的方法
        Method realMethod = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), method.getParameterTypes());
        // 参数下标
        int paramIndex = -1;
        boolean isVerify = false;
        Annotation[][] parameterAnnotations = realMethod.getParameterAnnotations();
        A: for (Annotation[] annotations : parameterAnnotations) {
            for (Annotation annotation : annotations) {
                paramIndex += 1;
                // 获取注解名
                if (annotation.annotationType().getName().equalsIgnoreCase(Valid.class.getName())) {
                    isVerify = true;
                    break A;
                }
            }
        }
        if (isVerify) {
            ParamsVerifyHandler.verify(args[paramIndex]);
        }
        return result;
    }
}
